package com.hmy.infrastructure.service.dingtalk.impl;

import com.hmy.infrastructure.api.bo.request.dingtalk.QueryDeptRequest;
import com.hmy.infrastructure.api.bo.response.dingtalk.CallBackResponse;
import com.hmy.infrastructure.api.bo.response.dingtalk.FailResult;
import com.hmy.infrastructure.api.bo.response.dingtalk.dept.DeptDetailResponse;
import com.hmy.infrastructure.api.bo.response.dingtalk.dept.DeptDetailResult;
import com.hmy.infrastructure.api.bo.response.dingtalk.dept.DeptIdListResponse;
import com.hmy.infrastructure.api.bo.request.dingtalk.DeptBo;
import com.hmy.infrastructure.service.dingtalk.IDingTalkDeptService;
import com.hmy.infrastructure.common.utils.DingTalkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

@Service
public class DingTalkDeptService implements IDingTalkDeptService {

    private static final Logger log = LoggerFactory.getLogger(DingTalkDeptService.class);
    @Resource
    private RestTemplate restTemplate;

    @Resource
    private DingTalkUtil dingTalkUtil;

    private static final String QUERY_DEPT_DETAIL = "https://oapi.dingtalk.com/topapi/v2/department/get";

    private static final String QUERY_DEPT_IDS = "https://oapi.dingtalk.com/topapi/v2/department/listsubid";

    private static final String QUERY_CALL_FAIL_EVENT = "https://oapi.dingtalk.com/call_back/get_call_back_failed_result";

    /**
     * 默认根部门id
     */
    public static final long ROOT_ID = 1;

    public List<DeptBo> syncDeptData() {
        List<DeptBo> list = syncDeptData(ROOT_ID, new ArrayList<>());
        dingTalkUtil.clearToken();
        return list;
    }

    private DeptBo convertToDept(DeptDetailResult result) {
        DeptBo dept = new DeptBo();
        BeanUtils.copyProperties(result, dept);
        return dept;
    }

    /**
     * 同步部门数据
     *
     * @param deptId 部门id
     * @return list 部门数据集合
     */
    public List<DeptBo> syncDeptData(Long deptId, List<DeptBo> list) {
        DeptBo dept = getDeptDetail(deptId, "sync");
        if (dept != null) {
            list.add(dept);
        }
        DeptIdListResponse res = getDeptIdList(deptId);
        if (res != null && null != res.getResult()) {
            for (Long id : res.getResult().getDeptIds()) {
                syncDeptData(id, list);
            }
        }
        return list;
    }

    /**
     * 查询部门详情
     *
     * @param deptId 部门id
     * @return 部门详情
     */
    public DeptBo getDeptDetail(long deptId, String type) {
        DeptBo dept = null;
        try {
            String url;
            if ("sync".equals(type)) {
                url = dingTalkUtil.createUrl(QUERY_DEPT_DETAIL);
            } else {
                url = dingTalkUtil.createUrlWithOutCache(QUERY_DEPT_DETAIL);
            }

            QueryDeptRequest req = new QueryDeptRequest(deptId);
            log.info("getDeptDetail parameter {},{}", url, req);
            DeptDetailResponse res = restTemplate.postForObject(url, req, DeptDetailResponse.class);
            if (res != null) {
                log.info("getDeptDetail process  {}", res);
                if (res.getResult() != null) {
                    dept = convertToDept(res.getResult());
                }
            }
        } catch (Exception e) {
            log.error("Query dept detail info exception", e);
        }
        return dept;
    }

    public DeptIdListResponse getDeptIdList(long deptId) {
        DeptIdListResponse res = null;
        try {
            String url = dingTalkUtil.createUrl(QUERY_DEPT_IDS);
            QueryDeptRequest req = new QueryDeptRequest(deptId);
            res = restTemplate.postForObject(url, req, DeptIdListResponse.class);
        } catch (Exception e) {
            log.error("Query dept id list exception", e);
        }
        return res;
    }

    public List<FailResult> getCallBackFail() {
        List<FailResult> failedList = null;
        try {
            String url = dingTalkUtil.createUrl(QUERY_CALL_FAIL_EVENT);
            URI uri = new URI(url);
            CallBackResponse res = restTemplate.getForObject(uri, CallBackResponse.class);
            if (res != null) {
                failedList = res.getFailedList();
            }
        } catch (Exception e) {
            throw new RuntimeException("Get call back event exception", e);
        }

        return failedList;
    }

}
